﻿Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Workflow.ComponentModel

Namespace System.Workflow.ComponentModel.Design
    Public Class SequentialActivityDesigner
        Inherits StructuredCompositeActivityDesigner
        ' Methods
        Private Function CreateConnectorDragDropGlyphs() As DesignerGlyph()
            Dim parentView As WorkflowView = MyBase.ParentView
            Dim service As DragDropManager = [TryCast](MyBase.GetService(GetType(DragDropManager)),DragDropManager)
            If (((parentView Is Nothing) OrElse (service Is Nothing)) OrElse (Not parentView.DragDropInProgress OrElse (MyBase.DrawingState <> DrawingStates.Valid))) Then
                Return New DesignerGlyph(0  - 1) {}
            End If
            Dim list As New List([Of] DesignerGlyph)
            Dim rectangle As Rectangle = parentView.ClientRectangleToLogical(New Rectangle(Point.Empty, parentView.ViewPortSize))
            Dim ambientTheme As AmbientTheme = WorkflowTheme.CurrentTheme.AmbientTheme
            Dim connectors As Rectangle() = Me.GetConnectors
            Dim helpTextRectangle As Rectangle = Me.HelpTextRectangle
            Dim i As Integer
            For i = 0 To connectors.Length - 1
                If ((rectangle.IntersectsWith(connectors(i)) AndAlso (i <> Me.CurrentDropTarget)) AndAlso service.IsValidDropContext(New ConnectorHitTestInfo(Me, HitTestLocations.Designer, i))) Then
                    Dim empty As Point = Point.Empty
                    If helpTextRectangle.IsEmpty Then
                        empty = New Point(((connectors(i).Location.X + (connectors(i).Size.Width / 2)) + 1), (connectors(i).Location.Y + (connectors(i).Size.Height / 2)))
                    Else
                        empty = New Point(((helpTextRectangle.Left + (helpTextRectangle.Width / 2)) + 1), (helpTextRectangle.Top - (ambientTheme.DropIndicatorSize.Height / 2)))
                    End If
                    list.Add(New ConnectorDragDropGlyph(i, empty))
                End If
            Next i
            Return list.ToArray
        End Function

        Protected Friend Overridable Function GetConnectors() As Rectangle()
            If (Not MyBase.ActiveDesigner Is Me) Then
                Return New Rectangle(0  - 1) {}
            End If
            If Not Me.Expanded Then
                Return New Rectangle(0  - 1) {}
            End If
            Dim designerTheme As CompositeDesignerTheme = [TryCast](MyBase.DesignerTheme,CompositeDesignerTheme)
            If (designerTheme Is Nothing) Then
                Return New Rectangle(0  - 1) {}
            End If
            Dim containedDesigners As ReadOnlyCollection([Of] ActivityDesigner) = Me.ContainedDesigners
            Dim num As Integer = If((containedDesigners.Count > 0), (2 + (containedDesigners.Count - 1)), 1)
            Dim rectangleArray As Rectangle() = New Rectangle(num  - 1) {}
            Dim innerConnections As ReadOnlyCollection([Of] Point) = Me.GetInnerConnections((DesignerEdges.Bottom Or DesignerEdges.Top))
            Dim point As New Point
            Dim point2 As New Point
            If ((Not innerConnections Is Nothing) AndAlso (innerConnections.Count > 0)) Then
                point = innerConnections.Item(0)
                point2 = innerConnections.Item((innerConnections.Count - 1))
            End If
            If (containedDesigners.Count > 0) Then
                Dim designer As ActivityDesigner = containedDesigners.Item(0)
                Dim connections As ReadOnlyCollection([Of] Point) = designer.GetConnections((DesignerEdges.Bottom Or DesignerEdges.Top))
                If (connections.Count = 0) Then
                    Dim bounds As Rectangle = designer.Bounds
                    connections = New List([Of] Point)() { New Point((bounds.Left + (bounds.Width / 2)), bounds.Top), New Point((bounds.Left + (bounds.Width / 2)), bounds.Bottom) }.AsReadOnly
                End If
                rectangleArray(0).Location = New Point((point.X - (If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0) / 2)), point.Y)
                Dim point3 As Point = connections.Item(0)
                rectangleArray(0).Size = New Size(If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0), (point3.Y - point.Y))
                Dim j As Integer
                For j = 0 To (containedDesigners.Count - 1) - 1
                    Dim designer2 As ActivityDesigner = containedDesigners.Item(j)
                    Dim designer3 As ActivityDesigner = containedDesigners.Item((j + 1))
                    If ((Not designer2 Is Nothing) AndAlso (Not designer3 Is Nothing)) Then
                        Dim onlys4 As ReadOnlyCollection([Of] Point) = designer2.GetConnections((DesignerEdges.Bottom Or DesignerEdges.Top))
                        Dim count As Integer = onlys4.Count
                        Dim onlys5 As ReadOnlyCollection([Of] Point) = designer3.GetConnections((DesignerEdges.Bottom Or DesignerEdges.Top))
                        Dim point4 As Point = onlys4.Item((count - 1))
                        Dim point5 As Point = onlys4.Item((count - 1))
                        rectangleArray((j + 1)).Location = New Point((point4.X - (If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0) / 2)), point5.Y)
                        Dim point6 As Point = onlys5.Item(0)
                        Dim point7 As Point = onlys4.Item((count - 1))
                        rectangleArray((j + 1)).Size = New Size(If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0), (point6.Y - point7.Y))
                    End If
                Next j
                Dim designer4 As ActivityDesigner = containedDesigners.Item((containedDesigners.Count - 1))
                Dim onlys6 As ReadOnlyCollection([Of] Point) = designer4.GetConnections((DesignerEdges.Bottom Or DesignerEdges.Top))
                If (onlys6.Count = 0) Then
                    Dim rectangle2 As Rectangle = designer4.Bounds
                    onlys6 = New List([Of] Point)() { New Point((rectangle2.Left + (rectangle2.Width / 2)), rectangle2.Top), New Point((rectangle2.Left + (rectangle2.Width / 2)), rectangle2.Bottom) }.AsReadOnly
                End If
                Dim point8 As Point = onlys6.Item((onlys6.Count - 1))
                Dim point9 As Point = onlys6.Item((onlys6.Count - 1))
                rectangleArray((num - 1)).Location = New Point((point8.X - (If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0) / 2)), point9.Y)
                Dim point10 As Point = onlys6.Item((onlys6.Count - 1))
                rectangleArray((num - 1)).Size = New Size(If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0), (point2.Y - point10.Y))
            Else
                rectangleArray(0).Location = New Point((point.X - (If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0) / 2)), point.Y)
                rectangleArray(0).Size = New Size(If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0), (point2.Y - point.Y))
            End If
            Dim i As Integer
            For i = 0 To rectangleArray.Length - 1
                rectangleArray(i).Inflate((3 * rectangleArray(i).Width), 0)
            Next i
            Return rectangleArray
        End Function

        Protected Overrides Function GetDropTargets(ByVal dropPoint As Point) As Rectangle()
            If Me.HelpTextRectangle.Contains(dropPoint) Then
                Return New Rectangle() { Me.HelpTextRectangle }
            End If
            Return Me.GetConnectors
        End Function

        Public Overrides Function GetNextSelectableObject(ByVal obj As Object, ByVal direction As DesignerNavigationDirection) As Object
            If (Not MyBase.ActiveDesigner Is Me) Then
                Return MyBase.GetNextSelectableObject(obj, direction)
            End If
            If ((direction <> DesignerNavigationDirection.Down) AndAlso (direction <> DesignerNavigationDirection.Up)) Then
                Return Nothing
            End If
            Dim activity As Object = Nothing
            Dim containedDesigners As ReadOnlyCollection([Of] ActivityDesigner) = Me.ContainedDesigners
            If (direction = DesignerNavigationDirection.Down) Then
                If TypeOf obj Is ConnectorHitTestInfo Then
                    Dim num As Integer = DirectCast(obj, ConnectorHitTestInfo).MapToIndex
                    If ((num >= 0) AndAlso (num < containedDesigners.Count)) Then
                        activity = containedDesigners.Item(num).Activity
                    End If
                    Return activity
                End If
                If TypeOf obj Is Activity Then
                    Dim designer As ActivityDesigner = ActivityDesigner.GetDesigner([TryCast](obj,Activity))
                    Dim num2 As Integer = If((Not designer Is Nothing), containedDesigners.IndexOf(designer), -1)
                    If ((num2 >= 0) AndAlso ((num2 + 1) < Me.GetConnectors.Length)) Then
                        activity = New ConnectorHitTestInfo(Me, HitTestLocations.Designer, (num2 + 1))
                    End If
                End If
                Return activity
            End If
            If (direction = DesignerNavigationDirection.Up) Then
                If TypeOf obj Is ConnectorHitTestInfo Then
                    Dim num3 As Integer = DirectCast(obj, ConnectorHitTestInfo).MapToIndex
                    If ((num3 > 0) AndAlso (num3 < Me.GetConnectors.Length)) Then
                        activity = containedDesigners.Item((num3 - 1)).Activity
                    End If
                    Return activity
                End If
                If TypeOf obj Is Activity Then
                    Dim designer2 As ActivityDesigner = ActivityDesigner.GetDesigner([TryCast](obj,Activity))
                    Dim connector As Integer = If((Not designer2 Is Nothing), containedDesigners.IndexOf(designer2), -1)
                    If ((connector >= 0) AndAlso (connector < Me.GetConnectors.Length)) Then
                        activity = New ConnectorHitTestInfo(Me, HitTestLocations.Designer, connector)
                    End If
                End If
            End If
            Return activity
        End Function

        Public Overrides Function HitTest(ByVal point As Point) As HitTestInfo
            If (Not MyBase.ActiveDesigner Is Me) Then
                Return MyBase.HitTest(point)
            End If
            Dim nowhere As HitTestInfo = HitTestInfo.Nowhere
            If Not Me.Expanded Then
                Return MyBase.HitTest(point)
            End If
            If ((Me.ContainedDesigners.Count = 0) AndAlso Me.HelpTextRectangle.Contains(point)) Then
                Return New ConnectorHitTestInfo(Me, HitTestLocations.Designer, 0)
            End If
            Dim connectors As Rectangle() = Me.GetConnectors
            Dim i As Integer
            For i = 0 To connectors.Length - 1
                If connectors(i).Contains(point) Then
                    nowhere = New ConnectorHitTestInfo(Me, HitTestLocations.Designer, i)
                    Exit For
                End If
            Next i
            If (nowhere.HitLocation = HitTestLocations.None) Then
                nowhere = MyBase.HitTest(point)
            End If
            Return nowhere
        End Function

        Protected Overrides Sub Initialize(ByVal activity As Activity)
            MyBase.Initialize(activity)
            Me.HelpText = DR.GetString("DropActivitiesHere", New Object(0  - 1) {})
        End Sub

        Protected Overrides Sub OnLayoutPosition(ByVal e As ActivityDesignerLayoutEventArgs)
            If (e Is Nothing) Then
                Throw New ArgumentNullException("e")
            End If
            MyBase.OnLayoutPosition(e)
            If (Me.Expanded AndAlso (MyBase.ActiveDesigner Is Me)) Then
                Dim designerTheme As CompositeDesignerTheme = [TryCast](e.DesignerTheme,CompositeDesignerTheme)
                Dim num As Integer = 0
                Dim innerConnections As ReadOnlyCollection([Of] Point) = Me.GetInnerConnections((DesignerEdges.Bottom Or DesignerEdges.Top))
                Dim point As Point = If((innerConnections.Count > 0), innerConnections.Item(0), Me.Location)
                If (Me.ContainedDesigners.Count = 1) Then
                    Dim num2 As Integer = 0
                    If (innerConnections.Count > 0) Then
                        Dim point2 As Point = innerConnections.Item((innerConnections.Count - 1))
                        Dim point3 As Point = innerConnections.Item(0)
                        num2 = (Me.Size.Height - (point2.Y - point3.Y))
                    End If
                    num = (num + (((Me.Size.Height - num2) / 2) - (Me.ContainedDesigners.Item(0).Size.Height / 2)))
                Else
                    num = (num + If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Height, 0))
                End If
                Dim designer As ActivityDesigner
                For Each designer In Me.ContainedDesigners
                    Dim size As Size = designer.Size
                    designer.Location = New Point((point.X - (size.Width / 2)), (point.Y + num))
                    num = (num + (size.Height + If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Height, 0)))
                Next
            End If
        End Sub

        Protected Overrides Function OnLayoutSize(ByVal e As ActivityDesignerLayoutEventArgs) As Size
            Dim size As Size = MyBase.OnLayoutSize(e)
            Dim designerTheme As CompositeDesignerTheme = [TryCast](e.DesignerTheme,CompositeDesignerTheme)
            If ((Me.Expanded AndAlso (MyBase.ActiveDesigner Is Me)) AndAlso (Not designerTheme Is Nothing)) Then
                If (Me.HelpText.Length > 0) Then
                    Me.helpTextSize = ActivityDesignerPaint.MeasureString(e.Graphics, designerTheme.Font, Me.HelpText, StringAlignment.Center, SequentialActivityDesigner.DefaultHelpTextSize)
                End If
                size.Height = (size.Height + designerTheme.ConnectorSize.Height)
                Dim designer As ActivityDesigner
                For Each designer In Me.ContainedDesigners
                    Dim size2 As Size = designer.Size
                    size.Width = Math.Max(size.Width, size2.Width)
                    size.Height = (size.Height + size2.Height)
                    size.Height = (size.Height + designerTheme.ConnectorSize.Height)
                Next
                If (Me.ContainedDesigners.Count = 0) Then
                    Dim helpTextRectangle As Rectangle = Me.HelpTextRectangle
                    size.Width = Math.Max(helpTextRectangle.Width, size.Width)
                    size.Height = (size.Height + helpTextRectangle.Height)
                    size.Height = (size.Height + designerTheme.ConnectorSize.Height)
                End If
                size.Width = Math.Max(size.Width, designerTheme.Size.Width)
                size.Width = (size.Width + (3 * e.AmbientTheme.Margin.Width))
                size.Width = (size.Width + (2 * e.AmbientTheme.SelectionSize.Width))
                size.Height = Math.Max(size.Height, designerTheme.Size.Height)
            End If
            Return size
        End Function

        Protected Overrides Sub OnPaint(ByVal e As ActivityDesignerPaintEventArgs)
            MyBase.OnPaint(e)
            Dim designerTheme As CompositeDesignerTheme = [TryCast](e.DesignerTheme,CompositeDesignerTheme)
            If (Me.Expanded AndAlso (Not designerTheme Is Nothing)) Then
                Dim helpTextRectangle As Rectangle = Me.HelpTextRectangle
                If ((Me.CurrentDropTarget = -1) AndAlso Not helpTextRectangle.Size.IsEmpty) Then
                    Dim connectors As Rectangle() = Me.GetConnectors
                    If (connectors.Length > 0) Then
                        Dim points As Point() = New Point() { New Point((connectors(0).X + (connectors(0).Width / 2)), (connectors(0).Y + 2)), New Point((connectors(0).X + (connectors(0).Width / 2)), (helpTextRectangle.Top - 2)) }
                        MyBase.DrawConnectors(e.Graphics, designerTheme.ForegroundPen, points, designerTheme.ConnectorStartCap, LineAnchor.None)
                        Dim pointArray2 As Point() = New Point() { New Point((connectors(0).X + (connectors(0).Width / 2)), (helpTextRectangle.Bottom + 2)), New Point((connectors(0).X + (connectors(0).Width / 2)), (connectors(0).Bottom - 2)) }
                        MyBase.DrawConnectors(e.Graphics, designerTheme.ForegroundPen, pointArray2, LineAnchor.None, designerTheme.ConnectorEndCap)
                    End If
                    ActivityDesignerPaint.DrawText(e.Graphics, designerTheme.Font, Me.HelpText, helpTextRectangle, StringAlignment.Center, e.AmbientTheme.TextQuality, designerTheme.ForegroundBrush)
                Else
                    Dim rectangleArray2 As Rectangle() = Me.GetConnectors
                    Dim i As Integer
                    For i = 0 To rectangleArray2.Length - 1
                        Dim pen As Pen = If((i = Me.CurrentDropTarget), e.AmbientTheme.DropIndicatorPen, designerTheme.ForegroundPen)
                        Dim startCap As LineAnchor = If((((i = 0) AndAlso (rectangleArray2.Length > 2)) OrElse (i = (rectangleArray2.Length - 1))), LineAnchor.None, designerTheme.ConnectorStartCap)
                        Dim endCap As LineAnchor = If(((i = 0) OrElse ((i = (rectangleArray2.Length - 1)) AndAlso (rectangleArray2.Length > 2))), LineAnchor.None, designerTheme.ConnectorEndCap)
                        Dim pointArray3 As Point() = New Point() { New Point((rectangleArray2(i).Left + (rectangleArray2(i).Width / 2)), (rectangleArray2(i).Top + 2)), New Point((rectangleArray2(i).Left + (rectangleArray2(i).Width / 2)), (rectangleArray2(i).Bottom - 2)) }
                        MyBase.DrawConnectors(e.Graphics, pen, pointArray3, startCap, endCap)
                    Next i
                End If
            End If
        End Sub


        ' Properties
        Public Overrides ReadOnly Property AccessibilityObject As AccessibleObject
            Get
                If (Me.accessibilityObject Is Nothing) Then
                    Me.accessibilityObject = New SequenceDesignerAccessibleObject(Me)
                End If
                Return Me.accessibilityObject
            End Get
        End Property

        Public Overrides ReadOnly Property CanExpandCollapse As Boolean
            Get
                If TypeOf MyBase.ParentDesigner Is ParallelActivityDesigner Then
                    Return False
                End If
                Return MyBase.CanExpandCollapse
            End Get
        End Property

        Public Overrides Property Expanded As Boolean
            Get
                Return (TypeOf MyBase.ParentDesigner Is ParallelActivityDesigner OrElse MyBase.Expanded)
            End Get
            Set(ByVal value As Boolean)
                If TypeOf MyBase.ParentDesigner Is ParallelActivityDesigner Then
                    value = True
                End If
                MyBase.Expanded = value
            End Set
        End Property

        Public Overrides ReadOnly Property FirstSelectableObject As Object
            Get
                If (Not MyBase.ActiveDesigner Is Me) Then
                    Return MyBase.FirstSelectableObject
                End If
                If (((Me.GetConnectors.Length <> 0) AndAlso Me.Expanded) AndAlso Me.IsVisible) Then
                    Return New ConnectorHitTestInfo(Me, HitTestLocations.Designer, 0)
                End If
                Return Nothing
            End Get
        End Property

        Protected Friend Overrides ReadOnly Property Glyphs As ActivityDesignerGlyphCollection
            Get
                Dim glyphs As New ActivityDesignerGlyphCollection
                Dim service As ISelectionService = [TryCast](MyBase.GetService(GetType(ISelectionService)),ISelectionService)
                If (Not service Is Nothing) Then
                    Dim obj2 As Object
                    For Each obj2 In service.GetSelectedComponents
                        Dim info As ConnectorHitTestInfo = [TryCast](obj2,ConnectorHitTestInfo)
                        If ((Not info Is Nothing) AndAlso (info.AssociatedDesigner Is Me)) Then
                            glyphs.Add(New SequentialConnectorSelectionGlyph(info.MapToIndex, (service.PrimarySelection Is obj2)))
                        End If
                    Next
                End If
                glyphs.AddRange(Me.CreateConnectorDragDropGlyphs)
                glyphs.AddRange(MyBase.Glyphs)
                Return glyphs
            End Get
        End Property

        Protected Overridable Property HelpText As String
            Get
                Return Me.helpText
            End Get
            Set(ByVal value As String)
                Me.helpText = value
                MyBase.PerformLayout
            End Set
        End Property

        Protected Overridable ReadOnly Property HelpTextRectangle As Rectangle
            Get
                Dim connectors As Rectangle() = Me.GetConnectors
                If (((Me.HelpText.Length = 0) OrElse (Me.ContainedDesigners.Count > 0)) OrElse (Not Me.Expanded OrElse (connectors.Length = 0))) Then
                    Return Rectangle.Empty
                End If
                Dim empty As Rectangle = Rectangle.Empty
                empty.X = ((connectors(0).Left + (connectors(0).Width / 2)) - (Me.helpTextSize.Width / 2))
                empty.Y = ((connectors(0).Top + (connectors(0).Height / 2)) - (Me.helpTextSize.Height / 2))
                empty.Size = Me.helpTextSize
                Return empty
            End Get
        End Property

        Protected ReadOnly Property HelpTextSize As Size
            Get
                Return Me.helpTextSize
            End Get
        End Property

        Public Overrides ReadOnly Property LastSelectableObject As Object
            Get
                If (Not MyBase.ActiveDesigner Is Me) Then
                    Return MyBase.LastSelectableObject
                End If
                Dim connectors As Rectangle() = Me.GetConnectors
                If (((connectors.Length <> 0) AndAlso Me.Expanded) AndAlso Me.IsVisible) Then
                    Return New ConnectorHitTestInfo(Me, HitTestLocations.Designer, (connectors.Length - 1))
                End If
                Return Nothing
            End Get
        End Property


        ' Fields
        Private accessibilityObject As SequenceDesignerAccessibleObject
        Private Shared ReadOnly DefaultHelpTextSize As Size = New Size(100, &H55)
        Private helpText As String = String.Empty
        Private helpTextSize As Size = Size.Empty

        ' Nested Types
        Private NotInheritable Class SequentialConnectorSelectionGlyph
            Inherits ConnectorSelectionGlyph
            ' Methods
            Public Sub New(ByVal connectorIndex As Integer, ByVal isPrimarySelectionGlyph As Boolean)
                MyBase.New(connectorIndex, isPrimarySelectionGlyph)
            End Sub

            Public Overrides Function GetBounds(ByVal designer As ActivityDesigner, ByVal activated As Boolean) As Rectangle
                Dim empty As Rectangle = Rectangle.Empty
                If TypeOf designer Is SequentialActivityDesigner Then
                    Dim connectors As Rectangle() = DirectCast(designer, SequentialActivityDesigner).GetConnectors
                    If (MyBase.connectorIndex < connectors.Length) Then
                        empty = connectors(MyBase.connectorIndex)
                    End If
                End If
                Return empty
            End Function

            Protected Overrides Sub OnPaint(ByVal graphics As Graphics, ByVal activated As Boolean, ByVal ambientTheme As AmbientTheme, ByVal designer As ActivityDesigner)
                Dim bounds As Rectangle = Me.GetBounds(designer, activated)
                Dim grabHandles As Rectangle() = New Rectangle() { New Rectangle(((bounds.X + (bounds.Width / 2)) - (ambientTheme.SelectionSize.Width / 2)), bounds.Y, ambientTheme.SelectionSize.Width, ambientTheme.SelectionSize.Height), New Rectangle(((bounds.X + (bounds.Width / 2)) - (ambientTheme.SelectionSize.Width / 2)), (bounds.Bottom - ambientTheme.SelectionSize.Height), ambientTheme.SelectionSize.Width, ambientTheme.SelectionSize.Height) }
                ActivityDesignerPaint.DrawGrabHandles(graphics, grabHandles, MyBase.isPrimarySelectionGlyph)
            End Sub


            ' Properties
            Public Overrides ReadOnly Property IsPrimarySelection As Boolean
                Get
                    Return MyBase.isPrimarySelectionGlyph
                End Get
            End Property

        End Class
    End Class
End Namespace

